<template>
  <div class="RegionSelector-city">
    <template>
      <el-select class="smallSelect" :size="size" v-if="!hideProvince" @change="getCities" v-model="currentProvince" :disabled="disabled">
        <el-option :value="placeholders.province">{{ placeholders.province }}</el-option>
        <el-option v-for="(item, index) in provinces"
                :value="item"
                :key="index">
          {{ item }}
        </el-option>
      </el-select>
      <template v-if="!onlyProvince">
        <el-select class="smallSelect" v-if="!hideCity" :size="size" @change="getAreas" v-model="currentCity" :disabled="disabled">
          <el-option :value="placeholders.city">{{ placeholders.city }}</el-option>
          <el-option v-for="(item, index) in cities"
                  :value="item"
                  :key="index">
            {{ item }}
          </el-option>
        </el-select>
        <el-select class="smallSelect" :size="size" @change="getStreets" v-if="!hideArea" v-model="currentArea" :disabled="disabled">
          <el-option :value="placeholders.area">{{ placeholders.area }}</el-option>
          <el-option v-for="(item, index) in areas "
                  :value="item"
                  :key="index">
            {{ item }}
          </el-option>
        </el-select>
        <el-select class="smallSelect" :size="size" @change="getCommunitys" v-if="!hideStreet" v-model="currentStreet" :disabled="disabled">
          <el-option :value="placeholders.street">{{ placeholders.street }}</el-option>
          <el-option v-for="(item, index) in streets "
                  :value="item"
                  :key="index">
            {{ item }}
          </el-option>
        </el-select>
        <el-select class="smallSelect" :size="size" v-if="!hideCommunity" v-model="currentCommunity" :disabled="disabled">
          <el-option :value="placeholders.community">{{ placeholders.community }}</el-option>
          <el-option v-for="(item, index) in communitys "
                  :value="item"
                  :key="index">
            {{ item }}
          </el-option>
        </el-select>
      </template>
    </template>
  </div>
</template>

<script>
import DISTRICTS from "./districts";

const DEFAULT_CODE = 100000;

export default {
  name: "RegionSelector",
  props: {
    size: { default: "small" },
    province: { type: [String, Number], default: "" },
    city: { type: [String, Number], default: "" },
    area: { type: [String, Number], default: "" },
    street: { type: [String, Number], default: "" },
    community: { type: [String, Number], default: "" },
    type: { type: String, default: "" },
    hideCommunity: { type: Boolean, default: false },
    hideStreet: { type: Boolean, default: false },
    hideArea: { type: Boolean, default: false },
    hideCity: { type: Boolean, default: false },
    hideProvince: { type: Boolean, default: false },
    onlyProvince: { type: Boolean, default: false },
    staticPlaceholder: { type: Boolean, default: false },
    placeholders: {
      type: Object,
      default() {
        return {
          province: "省",
          city: "市",
          area: "区",
          street: "街道",
          community: "社区"
        };
      }
    },
    disabled: { type: Boolean, default: false },
    addressHeader: { type: String, default: "address-header" },
    addressContainer: { type: String, default: "address-container" }
  },
  data() {
    return {
      tab: 1,
      showCityTab: false,
      showAreaTab: false,
      showStreetTab: false,
      showCommunityTab: false,
      provinces: [],
      cities: [],
      areas: [],
      streets: [],
      communitys: [],
      currentProvince:
        this.determineType(this.province) || this.placeholders.province,
      currentCity: this.determineType(this.city) || this.placeholders.city,
      currentArea: this.determineType(this.area) || this.placeholders.area,
      currentStreet:
        this.determineType(this.street) || this.placeholders.street,
      currentCommunity:
        this.determineType(this.community) || this.placeholders.community
    };
  },
  created() {
    this.provinces = this.getDistricts();
    this.cities = this.province
      ? this.getDistricts(this.getAreaCode(this.determineType(this.province)))
      : [];
    this.areas = this.city
      ? this.getDistricts(
          this.getAreaCode(this.determineType(this.city), this.area)
        )
      : [];
    this.streets = this.area
      ? this.getDistricts(
          this.getAreaCode(this.determineType(this.area), this.street)
        )
      : [];
    this.communitys = this.street
      ? this.getDistricts(
          this.getAreaCode(this.determineType(this.street), this.community)
        )
      : [];
  },
  watch: {
    currentProvince(value) {
      this.$emit("region", this.setData(value, this.currentProvince));
    },
    currentCity(value) {
      this.$emit("region", this.setData(value, this.currentProvince));
    },
    currentArea(value) {
      this.$emit("region", this.setData(value, this.currentProvince));
    },
    currentStreet(value) {
      this.$emit("region", this.setData(value, this.currentProvince));
    },
    currentCommunity(value) {
      this.$emit("region", this.setData(value, this.currentProvince));
    },
    province(value) {
      let temp = this;
      setTimeout(() => {
        temp.currentProvince =
          temp.determineType(value) || temp.placeholders.province;
        temp.cities = temp.determineValue(
          temp.currentProvince,
          temp.placeholders.province
        );
      }, 10);
    },
    city(value) {
      let temp = this;
      setTimeout(() => {
        temp.currentCity = temp.determineType(value) || temp.placeholders.city;
        temp.areas = temp.determineValue(
          temp.currentCity,
          temp.placeholders.city,
          temp.currentProvince
        );
      }, 15);
    },
    area(value) {
      let temp = this;
      setTimeout(() => {
        temp.currentArea = temp.determineType(value) || temp.placeholders.area;
        temp.streets = temp.determineValue(
          temp.currentArea,
          temp.placeholders.area,
          temp.currentProvince
        );
      }, 20);
    },
    street(value) {
      let temp = this;
      setTimeout(() => {
        temp.currentStreet =
          temp.determineType(value) || temp.placeholders.street;
        temp.communitys = temp.determineValue(
          temp.currentStreet,
          temp.placeholders.street,
          temp.currentProvince
        );
      }, 25);
    },
    community(value) {
      let temp = this;
      setTimeout(() => {
        temp.currentCommunity =
          temp.determineType(value) || temp.placeholders.community;
      }, 30);
    }
  },
  methods: {
    setData(value, check = "") {
      return {
        code: this.getAreaCode(value, check),
        value: value
      };
    },
    emit(name) {
      let data = {
        province: this.setData(this.currentProvince)
      };

      if (!this.onlyProvince) {
        this.$set(data, "city", this.setData(this.currentCity));
      }

      if (!this.onlyProvince || this.hideArea) {
        this.$set(data, "area", this.setData(this.currentArea));
      }

      this.$emit(name, data);
    },
    getCities() {
      this.currentCity = this.placeholders.city;
      this.currentArea = this.placeholders.area;
      this.currentStreet = this.placeholders.street;
      this.currentCommunity = this.placeholders.community;
      this.cities = this.determineValue(
        this.currentProvince,
        this.placeholders.province
      );
      this.cleanList("areas");
      this.cleanList("streets");
      this.cleanList("communitys");
      if (this.cities.length === 0) {
        this.emit("selected");
        this.tab = 1;
        this.showCityTab = false;
      }
    },
    getAreas() {
      this.currentArea = this.placeholders.area;
      this.currentStreet = this.placeholders.street;
      this.currentCommunity = this.placeholders.community;
      this.areas = this.determineValue(
        this.currentCity,
        this.placeholders.city,
        this.currentProvince
      );
      this.cleanList("streets");
      this.cleanList("communitys");
      if (this.areas.length === 0) {
        this.emit("selected");
        this.tab = 2;
        this.showAreaTab = false;
      }
    },
    getStreets() {
      this.currentStreet = this.placeholders.street;
      this.currentCommunity = this.placeholders.community;
      this.streets = this.determineValue(
        this.currentArea,
        this.placeholders.area,
        this.currentProvince
      );
      this.cleanList("communitys");
      if (this.streets.length === 0) {
        this.emit("selected");
        this.tab = 3;
        this.showStreetTab = false;
      }
    },
    getCommunitys() {
      this.currentCommunity = this.placeholders.community;
      this.communitys = this.determineValue(
        this.currentStreet,
        this.placeholders.street,
        this.currentProvince
      );
      if (this.communitys.length === 0) {
        this.emit("selected");
        this.tab = 4;
        this.showStreetTab = false;
      }
    },
    getAreaCodeByPreCode(name, preCode) {
      let codes = [];
      for (let x in DISTRICTS) {
        for (let y in DISTRICTS[x]) {
          if (name === DISTRICTS[x][y]) {
            codes.push(y);
          }
        }
      }

      if (codes.length > 1) {
        let index;
        codes.forEach((item, i) => {
          if (item.slice(0, 2) == preCode) {
            index = i;
          }
        });

        return codes[index];
      } else {
        return codes[0];
      }
    },
    getAreaCode(name, check = "") {
      for (let x in DISTRICTS) {
        for (let y in DISTRICTS[x]) {
          if (name === DISTRICTS[x][y]) {
            if (check.length > 0) {
              if (
                y.slice(0, 2) !==
                this.getAreaCodeByPreCode(check, y.slice(0, 2)).slice(0, 2)
              ) {
                continue;
              } else {
                return y;
              }
            } else {
              return y;
            }
          }
        }
      }
    },
    getCodeValue(code) {
      for (let x in DISTRICTS) {
        for (let y in DISTRICTS[x]) {
          if (code === parseInt(y)) {
            return DISTRICTS[x][y];
          }
        }
      }
    },
    getDistricts(code = DEFAULT_CODE) {
      return DISTRICTS[code] || [];
    },
    determineValue(currentValue, placeholderValue, check = "") {
      if (currentValue === placeholderValue) {
        return [];
      } else {
        return this.getDistricts(this.getAreaCode(currentValue, check));
      }
    },
    determineType(value) {
      if (typeof value === "number") {
        return this.getCodeValue(value);
      }
      return value;
    },
    cleanList(name) {
      this[name] = [];
    }
  }
};
</script>

<style scoped>
.dialog-areaCode_dept .RegionSelector-city .el-select--small,
.dialog-areaCode_User .RegionSelector-city .el-select--small {
  max-width: 150px !important;
}
.RegionSelector-city {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}
.RegionSelector-city .el-select--small {
  margin-right: 15px !important;
  margin-bottom: 15px !important;
}
</style>
